package labox.innovation.db.task;

import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Lock;

import labox.innovation.config.Config;
import labox.innovation.db.core.HeapByteBuffer;
import labox.innovation.db.core.SqlData;
import labox.innovation.db.manager.DBConnetionStateManager;
import labox.innovation.db.proxy.ConnectionProxy;
import labox.innovation.db.proxy.PreparedStatementProxy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ��д��������߳�
 * 
 * @author lian
 * 
 */
public class SaveThread extends Thread {
	private static Logger _log = LoggerFactory.getLogger(SaveThread.class);
	private static boolean saveThreadState = false;
	private boolean isRun = true;

	public static boolean isSaveThreadState() {
		return saveThreadState;
	}

	public static void setSaveThreadState(boolean State) {
		saveThreadState = State;
	}

	@Override
	public void run() {
		while (isRun) {
			if (_log.isDebugEnabled())
				_log.debug("��ʼ��д�������");
			LinkedList<SqlData> task = (LinkedList<SqlData>) DBConnetionStateManager.getDbTask();
			Lock writeLock = DBConnetionStateManager.writeLock;
			ConnectionProxy proxy = null;
			try {
				proxy = ConnectionProxy.newInstance();
				if (proxy != null) {
					writeLock.lock();
					writeBack(proxy, task);
					if (task.isEmpty()) {
						DBConnetionStateManager.updateDbState(true);
						saveThreadState = false;
						isRun = false;
						if (_log.isDebugEnabled())
							_log.debug("��ݻ�������Ѿ�д��");
					}
					writeLock.unlock();
				}
			} finally {
				if (proxy != null)
					proxy.close();
			}

		}
	}

	/**
	 * �����е����д����ݿ�
	 * 
	 * @param proxy
	 * @param task
	 * @throws SQLException
	 */
	private void writeBack(ConnectionProxy proxy, List<SqlData> task) {
		ConnectionProxy conn = proxy;
		PreparedStatementProxy ptmt = null;
		if (conn == null) {
			return;
		}
		SqlData data = null;
		int rs = 0;
		while (!task.isEmpty() && (data = task.get(0)) != null) {
			ptmt = proxy.prepareStatement(data.getSql());
			if (ptmt != null) {
				try {
					// ------------------
					Object[] params = data.getParams();
					if (params != null) {
						for (int i = 1; i <= params.length; i++) {
							Object values = params[i - 1];
							if (values == null) {
								task.remove(0);
								continue;
							}
							if (values instanceof String) {
								ptmt.setString(i, (String) values);
							}
							if (values instanceof Integer) {
								ptmt.setInt(i, (Integer) values);
							}
							if (values instanceof Long) {
								ptmt.setLong(i, (Long) values);
							}
							if (values instanceof Short) {
								ptmt.setShort(i, (Short) values);
							}
							if (values instanceof HeapByteBuffer) {
								ptmt.setBinaryStream(i, (HeapByteBuffer) values, ((HeapByteBuffer) values).limit());
							}
						}
						rs = ptmt.executeUpdate();
						// ���� HeapByteBuffer
						for (Object obj : params) {
							if (obj instanceof HeapByteBuffer)
								HeapByteBuffer.recycle((HeapByteBuffer) obj);
						}
					}

				} catch (SQLException e) {
					_log.error("���������д�뵽��ݿ�ʱ�������:" + data, Config.SERVER_ID, e);
				} finally {
					ptmt.close();
				}
				if (rs != PreparedStatementProxy.NETWORKDISCONNECTION) {
					task.remove(0);
					_log.info("���д�뵽��ݿ� :" + data, Config.SERVER_ID, data.getParams());
				}

			}
		}
	}
}
